home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / linux / src / atalnx_3.lzh / atari-linux-0.01pl3 / atari / atakeyb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-09  |  11.8 KB  |  538 lines

  1. /*
  2.  * linux/atari/atakeyb.c
  3.  *
  4.  * Atari Keyboard driver for 680x0 Linux
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. /*
  12.  * Atari support by Robert de Vries
  13.  * enhanced by Bjoern Brauel and Roman Hodek
  14.  */
  15.  
  16. #include <linux/config.h>
  17. #include <linux/sched.h>
  18. #include <linux/keyboard.h>
  19. #include <linux/delay.h>
  20. #include <linux/timer.h>
  21. #include <linux/interrupt.h>
  22.  
  23. #include <linux/ataritypes.h>
  24. #include <linux/atariints.h>
  25. #include <linux/atarihw.h>
  26. #include <linux/atarikb.h>
  27. #include <linux/atari_mouse.h>
  28. #include <linux/atari_joystick.h>
  29.  
  30. extern void process_scancode (int);
  31. static void atakeyb_rep( unsigned long ignore );
  32.  
  33. #define ATAKEY_CAPS    (58)
  34. #define BREAK_MASK    (0x80)
  35.  
  36. typedef enum kb_state_t
  37. {
  38.     KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK
  39. } KB_STATE_T;
  40.  
  41. typedef struct keyboard_state
  42. {
  43.     unsigned char  buf[6];
  44.     int        len;
  45.     KB_STATE_T       state;
  46. } KEYBOARD_STATE;
  47.  
  48. KEYBOARD_STATE kb_state;
  49.  
  50. #define    DEFAULT_KEYB_REP_DELAY    (HZ/4)
  51. #define    DEFAULT_KEYB_REP_RATE    (HZ/25)
  52.  
  53. unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
  54. unsigned int key_repeat_rate  = DEFAULT_KEYB_REP_RATE;
  55.  
  56.  
  57. #if 0
  58.  
  59. /*
  60.  * This table maps the Atari keyboard scan codes to
  61.  * the Linux "virtual" scan codes.  These "virtual" scan
  62.  * codes mostly conform to the scan codes given by an IBM
  63.  * keyboard, except that the E0 xx codes are given unique
  64.  * codes.  These are the codes > 96.  See linux/keyboard.h
  65.  */
  66.  
  67. static unsigned char atari_kmap[] =
  68. {
  69. /* 00-03 */    KB_NONE,       KB_ESCAPE,    KB_1,      KB_2,
  70. /* 04-07 */    KB_3,          KB_4,        KB_5,      KB_6,
  71. /* 08-0B */    KB_7,          KB_8,        KB_9,      KB_0,
  72. /* 0C-0F */    KB_DASH,       KB_EQUAL,     KB_BACKSPACE, KB_TAB,
  73. /* 10-13 */    KB_Q,          KB_W,        KB_E,      KB_R,
  74. /* 14-17 */    KB_T,          KB_Y,        KB_U,      KB_I,
  75. /* 18-1B */    KB_O,          KB_P,        KB_LSQUARE,   KB_RSQUARE,
  76. /* 1C-1F */    KB_ENTER,      KB_LCTRL,        KB_A,      KB_S,
  77. /* 20-23 */    KB_D,          KB_F,        KB_G,      KB_H,
  78. /* 24-27 */    KB_J,          KB_K,        KB_L,      KB_SEMICOLON,
  79. /* 28-2B */    KB_APOSTROPHE, KB_BACKQUOTE, KB_LSHIFT,    KB_BACKSLASH,
  80. /* 2C-2F */    KB_Z,          KB_X,        KB_C,      KB_V,
  81. /* 30-33 */    KB_B,          KB_N,        KB_M,         KB_COMMA,
  82. /* 34-37 */    KB_PERIOD,     KB_SLASH,     KB_RSHIFT,    KB_NONE,
  83. /* 38-3B */    KB_LALT,       KB_SPACE,     KB_CAPS,      KB_F1,
  84. /* 3C-3F */    KB_F2,         KB_F3,        KB_F4,      KB_F5,
  85. /* 40-43 */    KB_F6,         KB_F7,        KB_F8,      KB_F9,
  86. /* 44-47 */    KB_F10,        KB_NONE,      KB_NONE,      KB_FIND,
  87. /* 48-4B */    KB_UP,         KB_NONE,        KB_KPMINUS,   KB_LEFT,
  88. /* 4C-4F */    KB_NONE,       KB_RIGHT,     KB_KPPLUS,    KB_NONE,
  89. /* 50-53 */    KB_DOWN,       KB_NONE,        KB_INSERT,      KB_DELETE,
  90. /* 54-57 */    KB_NONE,          KB_NONE,        KB_NONE,      KB_NONE,
  91. /* 58-5B */    KB_NONE,          KB_NONE,        KB_NONE,      KB_NONE,
  92. /* 5B-5F */    KB_NONE,       KB_NONE,      KB_NONE,      KB_NONE,
  93. /* 60-63 */    KB_LESS,       KB_UNDO,      KB_HELP,      KB_KPLPAR,
  94. /* 64-67 */    KB_KPRPAR,     KB_KPDIVIDE,  KB_KPMULTIPLY,KB_KP7,
  95. /* 68-6B */    KB_KP8,        KB_KP9,        KB_KP4,      KB_KP5,
  96. /* 6C-6F */    KB_KP6,        KB_KP1,        KB_KP2,      KB_KP3,
  97. /* 70-73 */    KB_KP0,        KB_KPDECIMAL, KB_KPENTER,      KB_NONE,
  98. /* 74-77 */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE,
  99. /* 78-7B */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE,
  100. /* 7C-7F */    KB_NONE,       KB_NONE,        KB_NONE,      KB_NONE
  101. };
  102.  
  103. #endif
  104.  
  105.  
  106. static unsigned char rep_scancode;
  107. static struct timer_list atakeyb_rep_timer = { NULL, 0, 0, atakeyb_rep };
  108.  
  109.  
  110. static void atakeyb_rep( unsigned long ignore )
  111.  
  112. {
  113.     atakeyb_rep_timer.expires = key_repeat_rate;
  114.     add_timer( &atakeyb_rep_timer );
  115.     process_scancode( rep_scancode );
  116. }
  117.  
  118.  
  119. static void keyboard_interrupt(struct  intframe *fp, void *data)
  120. {
  121.   u_char acia_stat;
  122.   int scancode;
  123.   int break_flag;
  124.  
  125.   acia_stat = acia.key_ctrl;
  126.   /* check out if the interrupt came from this ACIA */
  127.   if (!(acia_stat & ACIA_IRQ))
  128.     return;
  129.  
  130.     if (acia_stat & ACIA_RDRF)    /* received a character */
  131.     {
  132.     scancode = acia.key_data;    /* get it or reset the ACIA, I'll get it! */
  133.     switch (kb_state.state)
  134.     {
  135.       case KEYBOARD:
  136.         switch (scancode)
  137.         {
  138.           case 0xF7:
  139.         kb_state.state = AMOUSE;
  140.         kb_state.len = 0;
  141.         break;
  142.  
  143.           case 0xF8:
  144.           case 0xF9:
  145.                case 0xFA:
  146.           case 0xFB:
  147.         kb_state.state = RMOUSE;
  148.             kb_state.len = 1;
  149.         kb_state.buf[0] = scancode;
  150.         break;
  151.  
  152.           case 0xFC:
  153.         kb_state.state = CLOCK;
  154.         kb_state.len = 0;
  155.         break;
  156.  
  157.           case 0xFE:
  158.           case 0xFF:
  159.         kb_state.state = JOYSTICK;
  160.         kb_state.len = 1;
  161.         kb_state.buf[0] = scancode;
  162.         break;
  163.  
  164.           default:
  165.         break_flag = scancode & BREAK_MASK;
  166.         scancode &= ~BREAK_MASK;
  167.  
  168.         if (break_flag) {
  169.             del_timer( &atakeyb_rep_timer );
  170.             rep_scancode = 0;
  171.         }
  172.         else {
  173.             del_timer( &atakeyb_rep_timer );
  174.             rep_scancode = scancode;
  175.             atakeyb_rep_timer.expires = key_repeat_delay;
  176.             add_timer( &atakeyb_rep_timer );
  177.         }
  178.  
  179.         process_scancode( break_flag | scancode );
  180.         break;
  181.         }
  182.         break;
  183.  
  184.       case AMOUSE:
  185.         kb_state.buf[kb_state.len++] = scancode;
  186.         if (kb_state.len == 5)
  187.         {
  188.         kb_state.state = KEYBOARD;
  189.         /* not yet used */
  190.         /* wake up someone waiting for this */
  191.         }
  192.         break;    
  193.  
  194.       case RMOUSE:
  195.         kb_state.buf[kb_state.len++] = scancode;
  196.         if (kb_state.len == 3)
  197.         {
  198.         kb_state.state = KEYBOARD;
  199.         mouse_interrupt(kb_state.buf);
  200.         }
  201.         break;
  202.  
  203.       case JOYSTICK:
  204.         kb_state.buf[1] = scancode;
  205.         kb_state.state = KEYBOARD;
  206.         joystick_interrupt(kb_state.buf);
  207.         break;
  208.  
  209.       case CLOCK:
  210.         kb_state.buf[kb_state.len++] = scancode;
  211.         if (kb_state.len == 6)
  212.         {
  213.         kb_state.state = KEYBOARD;
  214.         /* wake up someone waiting for this.
  215.            But will this ever be used, as Linux keeps its own time.
  216.            Perhaps for synchronization purposes? */
  217.         /* wake_up_interruptible(&clock_wait); */
  218.         }
  219.         break;
  220.     }
  221.     }
  222.  
  223. #ifdef KEYB_WRITE_INTERRUPT
  224.     if (acia_stat & ACIA_TDRE)    /* transmit of character is finished */
  225.     {
  226.     if (kb_state.buf)
  227.     {
  228.         acia.key_data = *kb_state.buf++;
  229.         kb_state.len--;
  230.         if (kb_state.len == 0)
  231.         {
  232.         kb_state.buf = NULL;
  233.         if (!kb_state.kernel_mode)
  234.             /* unblock something */;
  235.         }
  236.     }
  237.     }
  238. #endif
  239.  
  240. #if 0
  241.     if (acia_stat & ACIA_CTS)
  242.     /* cannot happen */;
  243. #endif
  244.  
  245.     if (acia_stat & (ACIA_FE | ACIA_PE))
  246.     {
  247.     panic("Error in keyboard communication");
  248.     }
  249.  
  250.     if (acia_stat & ACIA_OVRN)
  251.     {
  252.     /* a very fast typist or a slow system, give a warning */    
  253.     }
  254. }
  255.  
  256. #ifdef KEYB_WRITE_INTERRUPT
  257. void ikbd_write(char *str, int len)
  258. {
  259.     u_char acia_stat;
  260.  
  261.     if (kb_stat.buf)
  262.     /* wait */;
  263.     acia_stat = acia.key_ctrl;
  264.     if (acia_stat & ACIA_TDRE)
  265.     {
  266.     if (len != 1)
  267.     {
  268.         kb_stat.buf = str 1;
  269.         kb_stat.len = len - 1;
  270.     }
  271.     acia.key_data = *str;
  272.     /* poll */
  273.     }
  274. }
  275. #else
  276. /*
  277.  * I write to the keyboard without using interrupts, I poll instead.
  278.  * This takes for the maximum length string allowed (7) at 7812.5 baud
  279.  * 8 data 1 start 1 stop bit: 9.0 ms
  280.  * If this takes too long for normal operation, interrupt driven writing
  281.  * is the solution. (I made a feeble attempt in that direction but I
  282.  * kept it simple for now.)
  283.  */
  284. void ikbd_write(char *str, int len)
  285. {
  286.     u_char acia_stat;
  287.  
  288.     if ((len < 1) || (len > 7))
  289.     panic("ikbd: maximum string length exceeded");
  290.     while (len)
  291.     {
  292.     acia_stat = acia.key_ctrl;
  293.     if (acia_stat & ACIA_TDRE)
  294.     {
  295.         acia.key_data = *str++;
  296.         len--;
  297.     }
  298.     }
  299. }
  300. #endif
  301.  
  302. /* Reset (without touching the clock) */
  303. void ikbd_reset(void)
  304. {
  305.     static char cmd[2] = { 0x80, 0x01 };
  306.     
  307.     ikbd_write(cmd, 2);
  308.  
  309.     /* if allswell code 0xF1 is returned, else the break codes of
  310.        all keys making contact */
  311. }
  312.  
  313. /* Set mouse button action */
  314. void ikbd_mouse_button_action(int mode)
  315. {
  316.     char cmd[2] = { 0x07, mode };
  317.  
  318.     ikbd_write(cmd, 2);
  319. }
  320.  
  321. /* Set relative mouse position reporting */
  322. void ikbd_mouse_rel_pos(void)
  323. {
  324.     static char cmd[1] = { 0x08 };
  325.  
  326.     ikbd_write(cmd, 1);
  327. }
  328.  
  329. /* Set absolute mouse position reporting */
  330. void ikbd_mouse_abs_pos(int xmax, int ymax)
  331. {
  332.     char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
  333.  
  334.     ikbd_write(cmd, 5);
  335. }
  336.  
  337. /* Set mouse keycode mode */
  338. void ikbd_mouse_kbd_mode(int dx, int dy)
  339. {
  340.     char cmd[3] = { 0x0A, dx, dy };
  341.  
  342.     ikbd_write(cmd, 3);
  343. }
  344.  
  345. /* Set mouse threshold */
  346. void ikbd_mouse_thresh(int x, int y)
  347. {
  348.     char cmd[3] = { 0x0B, x, y };
  349.  
  350.     ikbd_write(cmd, 3);
  351. }
  352.  
  353. /* Set mouse scale */
  354. void ikbd_mouse_scale(int x, int y)
  355. {
  356.     char cmd[3] = { 0x0C, x, y };
  357.  
  358.     ikbd_write(cmd, 3);
  359. }
  360.  
  361. /* Interrogate mouse position */
  362. void ikbd_mouse_pos_get(int *x, int *y)
  363. {
  364.     static char cmd[1] = { 0x0D };
  365.  
  366.     ikbd_write(cmd, 1);
  367.  
  368.     /* wait for returning bytes */
  369. }
  370.  
  371. /* Load mouse position */
  372. void ikbd_mouse_pos_set(int x, int y)
  373. {
  374.     char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
  375.  
  376.     ikbd_write(cmd, 6);
  377. }
  378.  
  379. /* Set Y=0 at bottom */
  380. void ikbd_mouse_y0_bot(void)
  381. {
  382.     static char cmd[1] = { 0x0F };
  383.  
  384.     ikbd_write(cmd, 1);
  385. }
  386.  
  387. /* Set Y=0 at top */
  388. void ikbd_mouse_y0_top(void)
  389. {
  390.     static char cmd[1] = { 0x10 };
  391.  
  392.     ikbd_write(cmd, 1);
  393. }
  394.  
  395. /* Resume */
  396. void ikbd_resume(void)
  397. {
  398.     static char cmd[1] = { 0x11 };
  399.  
  400.     ikbd_write(cmd, 1);
  401. }
  402.  
  403. /* Disable mouse */
  404. void ikbd_mouse_disable(void)
  405. {
  406.     static char cmd[1] = { 0x12 };
  407.  
  408.     ikbd_write(cmd, 1);
  409. }
  410.  
  411. /* Pause output */
  412. void ikbd_pause(void)
  413. {
  414.     static char cmd[1] = { 0x13 };
  415.  
  416.     ikbd_write(cmd, 1);
  417. }
  418.  
  419. /* Set joystick event reporting */
  420. void ikbd_joystick_event_on(void)
  421. {
  422.     static char cmd[1] = { 0x14 };
  423.  
  424.     ikbd_write(cmd, 1);
  425. }
  426.  
  427. /* Set joystick interrogation mode */
  428. void ikbd_joystick_event_off(void)
  429. {
  430.     static char cmd[1] = { 0x15 };
  431.  
  432.     ikbd_write(cmd, 1);
  433. }
  434.  
  435. /* Joystick interrogation */
  436. void ikbd_joystick_get_state(void)
  437. {
  438.     static char cmd[1] = { 0x16 };
  439.  
  440.     ikbd_write(cmd, 1);
  441. }
  442.  
  443. #if 0
  444. /* This disables all other ikbd activities !!!! */
  445. /* Set joystick monitoring */
  446. void ikbd_joystick_monitor(int rate)
  447. {
  448.     static char cmd[2] = { 0x17, rate };
  449.  
  450.     ikbd_write(cmd, 2);
  451.  
  452.     kb_state.state = JOYSTICK_MONITOR;
  453. }
  454. #endif
  455.  
  456. /* some joystick routines not in yet (0x18-0x19) */
  457.  
  458. /* Disable joysticks */
  459. void ikbd_joystick_disable(void)
  460. {
  461.     static char cmd[1] = { 0x1A };
  462.  
  463.     ikbd_write(cmd, 1);
  464. }
  465.  
  466. /* Time-of-day clock set */
  467. void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
  468. {
  469.     char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
  470.  
  471.     ikbd_write(cmd, 7);
  472. }
  473.  
  474. /* Interrogate time-of-day clock */
  475. void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
  476. {
  477.     static char cmd[1] = { 0x1C };
  478.  
  479.     ikbd_write(cmd, 1);
  480. }
  481.  
  482. /* Memory load */
  483. void ikbd_mem_write(int address, int size, char *data)
  484. {
  485.     panic("Attempt to write data into keyboard memory");
  486. }
  487.  
  488. /* Memory read */
  489. void ikbd_mem_read(int address, char data[6])
  490. {
  491.     char cmd[3] = { 0x21, address>>8, address&0xFF };
  492.  
  493.     ikbd_write(cmd, 3);
  494.  
  495.     /* receive data and put it in data */
  496. }
  497.  
  498. /* Controller execute */
  499. void ikbd_exec(int address)
  500. {
  501.     char cmd[3] = { 0x22, address>>8, address&0xFF };
  502.  
  503.     ikbd_write(cmd, 3);
  504. }
  505.  
  506. /* Status inquiries (0x87-0x9A) not yet implemented */
  507.  
  508. unsigned long atari_keyb_init(unsigned long kmem_start)
  509. {
  510.  
  511.   acia.key_ctrl = ACIA_RESET;        /* reset ACIA */
  512.  
  513.   /* divide 500kHz by 64 gives 7812.5 baud */
  514.   /* 8 data no parity 1 start 1 stop bit */
  515.   /* receive interrupt enabled */
  516. #ifdef KEYB_WRITE_INTERRUPT
  517.   /* RTS low, transmit interrupt enabled */
  518.   acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTIE|ACIA_RIE);
  519. #else
  520.   /* RTS low, transmit interrupt disabled */
  521.   acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTID|ACIA_RIE);
  522. #endif
  523.  
  524.     add_isr(IRQ_MFP_ACIA, keyboard_interrupt, 0, NULL);
  525.  
  526.     ikbd_reset();
  527.     ikbd_mouse_disable();
  528.     ikbd_joystick_disable();
  529.  
  530.     kb_state.state = KEYBOARD;
  531.     kb_state.len = 0;
  532.  
  533.     /* enable ACIA Interrupts */ 
  534.     mfp.int_en_b |= 0x40;
  535.  
  536.   return kmem_start;
  537. }
  538.